package com.xjj.sso.server.ticket;

import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.xjj.framework.utils.EncryptUtils;
import com.xjj.sso.server.pojo.User;
import com.xjj.sso.server.util.URLUtils;

public class GrantingTicket extends Ticket implements Comparable<GrantingTicket>{
	
	private static final long serialVersionUID = 1L;
	private static String PREFIX_GT = "XGT_";
	private static String PREFIX_ST = "XST_";
	private ConcurrentHashMap<String,ServiceTicket> serviceTicketMap = new ConcurrentHashMap<String,ServiceTicket>();
	private User user;
	
	/**
	 * 生成GrantingTicket
	 * @param user
	 * @return
	 */
	public static GrantingTicket generateGrantingTicket(User user)
	{
		String gtId = generateGrantingTicketId(user);
		
		GrantingTicket gt = new GrantingTicket();
		gt.setId(gtId);
		gt.setExpired(false);
		gt.setCreationTime(new Date());
		gt.setUser(user);
		
		return gt;
	}
	
	/**
	 * 生成gtId
	 * @param user
	 * @return
	 */
	public static String generateGrantingTicketId(User user)
	{
		StringBuilder preTicketSB = new StringBuilder(user.getLoginName());
		preTicketSB.append(user.getUserId());
		preTicketSB.append(System.currentTimeMillis());
		
		String cookieTicket = EncryptUtils.MD5Encode(preTicketSB.toString());
		return PREFIX_GT+cookieTicket;
	}
	
	
	/**
	 * 生成GrantingTicket
	 * @param user
	 * @param grantingTicket
	 * @return
	 */
	public static GrantingTicket generateGrantingTicket(User user,String grantingTicket)
	{
		GrantingTicket gt = new GrantingTicket();
		gt.setId(grantingTicket);
		gt.setExpired(false);
		gt.setCreationTime(new Date());
		gt.setUser(user);
		
		return gt;
	}
	
	/**
	 * 生成ServiceTicket
	 * @param service
	 * @return
	 */
	public static ServiceTicket generateServiceTicket(String service)
	{
		String serviceTicket = EncryptUtils.MD5Encode(service+System.currentTimeMillis());
		
		ServiceTicket st = new ServiceTicket();
		st.setId(PREFIX_ST+serviceTicket);
		st.setExpired(false);
		st.setCreationTime(new Date());
		st.setService(service);
		st.setHost(URLUtils.getUriFromUrl(service));
		return st;
	}
	
	
	/**
	 * 根据ticket和service获得ServiceTicket
	 * @param ticket
	 * @param service
	 * @return
	 */
	public ServiceTicket getServiceTicket(String ticket,String service)
	{
		ServiceTicket st = serviceTicketMap.get(ticket);
		if(null == st)
		{
			return null;
		}
		
		if(null == service)
		{
			return st;
		}
		
		if(service.equals(st.getService()))
		{
			return st;
		}else
		{
			return null;
		}
	}
	
	/**
	 * 缓存ServiceTicket
	 * @param st
	 */
	public void  putServiceTicket(ServiceTicket st)
	{
		serviceTicketMap.put(st.getId(), st);
	}
	
	/**
	 * 从缓存中清除ServiceTicket
	 * @param st
	 */
	public void removeServiceTicket(String st)
	{
		if(serviceTicketMap.containsKey(st))
		{
			serviceTicketMap.remove(st);
		}
	}
	
	/**
	 * 使ServiceTicket过期
	 * @param st
	 */
	public void expiredServiceTicket(String st)
	{
		if(null == st)
		{
			return;
		}
		if(serviceTicketMap.containsKey(st))
		{
			ServiceTicket serviceTicket = serviceTicketMap.get(st);
			serviceTicket.setExpired(true);
			serviceTicketMap.put(st, serviceTicket);
		}
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public ConcurrentHashMap<String, ServiceTicket> getServiceTicketMap() {
		return serviceTicketMap;
	}
	
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("###gt="+this.getId()+"&userName="+user.getUserName()+"###\n");
		Set<String> keySet = serviceTicketMap.keySet();
		for (Iterator<String> iterator = keySet.iterator(); iterator.hasNext();) {
			String ticket = (String) iterator.next();
			sb.append(serviceTicketMap.get(ticket));
			sb.append("\n");
		}
		return sb.toString();
	}

	public int compareTo(GrantingTicket gt) {
		if(getCreationTime() == null)
		{
			return -1; 
		}
		
		if(null==gt)
		{
			return 1;
		}
		
		if(null == gt.getCreationTime())
		{
			return 1; 
		}
		if(this.getCreationTime().getTime()>gt.getCreationTime().getTime())
		{
			return -1;
		}else if(getCreationTime().getTime() == gt.getCreationTime().getTime())
		{
			return 0;
		}else
		{
			return 1;
		}
		
	}
}